package CB_C19;

import javax.media.*;
import javax.media.Format;
import javax.media.format.*;
import java.util.Random;

/**MyEffect
 * Created on 10.01.2010. <br>
 <br>
 Framedrop Effect
 *<br>
 * @author Sebastian Czekierski, Stefan Blumberger
 *
 */

public class MyEffect implements Effect
{
    Format[] inputFormats;
    Format[] outputFormats;
    Format outputFormat;
    Format inputFormat;

    /**Strength*/
    int strength = 0;
    /**Abstand: needed for Framedrop effect*/
    int abstand = 0;
    /**counter a: needed for Framedrop effect*/
    int a = 0;
    /**counter s: needed for Framedrop effect*/
    int s = 0;
    /**when true, a random number is calculated for abstand*/
    boolean random = false;
    /**Tmp is used to store a Frame temporarely*/
    private Buffer tmp;
    /**store duration of the effect*/
    private int duration;
    /**store begin of the effect*/
    private int begin;
    /**store framerate of the video*/
    private double framerate;

    /**Constructor*/
    public MyEffect(boolean random, int in_strength,String duration,String begin,float framerate)
    {
        this.random = random;
        this.strength = in_strength;
        this.duration = new Integer(duration);
        this.begin = new Integer(begin);
        this.framerate = framerate;

        /**Set Random abstand if true*/
        if(random)
             abstand = new Random().nextInt(10);
        else
            abstand = strength;

        /**Convert*/
        outputFormats = new Format[]
        {
                new RGBFormat
                (
                null,
                Format.NOT_SPECIFIED,
                Format.intArray,
                Format.NOT_SPECIFIED, 32,
                Format.NOT_SPECIFIED,
                Format.NOT_SPECIFIED,
                Format.NOT_SPECIFIED
                )
        };
        inputFormats = new Format[]
        {
                new RGBFormat
                (
                null,
                Format.NOT_SPECIFIED,
                Format.intArray,
                Format.NOT_SPECIFIED, 32,
                Format.NOT_SPECIFIED,
                Format.NOT_SPECIFIED,
                Format.NOT_SPECIFIED
                )
        };
    }
    public Format[] getSupportedInputFormats()
    {
	return inputFormats;
    }
    public Format[] getSupportedOutputFormats(Format input)
    {
        if (input==null)
            return(outputFormats);
        if (input instanceof RGBFormat)
            return(new Format[] {input,outputFormats[0]});
        else
            return(outputFormats);
   }
   public Format setInputFormat(Format input)
   {
        if (input instanceof RGBFormat)
        {
            this.inputFormat = (RGBFormat) input;
            return inputFormat;
        }
        else
            return null;
   }

   public Format setOutputFormat(Format output)
   {
            if (output instanceof RGBFormat)
                outputFormat = (RGBFormat)output;
            else
                outputFormat = (RGBFormat)outputFormats[0];

        return(outputFormat);
 }
   /**processes one frame at a time and overwrites a frame if necessary*/
   public int process(Buffer in, Buffer out)
   {
        out.copy(in,true);
        double timestamp = (in.getSequenceNumber())/framerate;

        /**Don't continue if effect is not applied*/
        if(timestamp < begin || timestamp > (begin+duration))
        {
            return BUFFER_PROCESSED_OK;
        }

        /**do not "remove" a frame*/
        if(a<abstand)
         {
             a++;
         }

         /**start "removing" frames*/
         if(a == abstand) //Frames entfernen
         {
              if(s<strength)
              {
                  /*--------Overwrite current frame------*/

                  if(s == 0)
                  {
                      /**save current frame temporarely*/
                      tmp = new Buffer();
                      tmp.copy(in,true);
                  }
                  /**copy tmp frame into current frame*/
                  out.copy(tmp,true);
                  s++;
              }
              /**reset a and s*/
              if(s == strength)
              {
                  a=0;
                  s=0;
                  if(random)
                  {
                      abstand = new Random().nextInt(10); //neuen random abstand
                  }
              }
         }
        return BUFFER_PROCESSED_OK;
   }
   public String getName()
   {
     return "Effect_anzahl";
 }
   public void open()
   {
 }
   public void close()
   {
   }
   public void reset()
   {
 }
   public Object[] getControls()
   {
       return null;
   }
   public Object getControl(String arg0)
   {
     return this;
   }
   public void SetRandom(boolean in_random)
   {
   this.random = in_random;
}
   public void SetStrength(int in_strength)
   {
   this.strength = in_strength;
}
}